package com.example.bingobox.dialog;

import android.app.Dialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.app.ProgressDialog;
import android.location.Geocoder;
import android.location.Address;
import java.util.Locale;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.example.bingobox.R;
import com.example.bingobox.model.State.Location;
import com.example.bingobox.utils.LocationUtils;

import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.GeocodeQuery;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch.OnGeocodeSearchListener;

public class CitySearchDialog extends DialogFragment implements PoiSearch.OnPoiSearchListener, OnGeocodeSearchListener {
    private OnCitySelectedListener listener;
    private ArrayAdapter<String> adapter;
    private List<PoiItem> poiResults = new ArrayList<>();
    private List<Location> addressResults = new ArrayList<>();
    private ListView resultList;
    private AMapLocationClient locationClient;
    private static final int LOCATION_TIMEOUT = 30000; // 30秒定位超时
    private Handler timeoutHandler = new Handler(Looper.getMainLooper());
    private ProgressDialog progressDialog;
    private static final int SEARCH_TYPE_CITY = 1;
    private static final int SEARCH_TYPE_LOCATION = 2;
    private int currentSearchType = SEARCH_TYPE_CITY;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            AMapLocationClient.updatePrivacyShow(requireContext(), true, true);
            AMapLocationClient.updatePrivacyAgree(requireContext(), true);
            locationClient = new AMapLocationClient(requireContext());
            
            AMapLocationClientOption option = new AMapLocationClientOption();
            option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            option.setNeedAddress(true);
            option.setHttpTimeOut(20000);
            locationClient.setLocationOption(option);
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(requireContext(), 
                "初始化定位服务失败: " + e.getMessage(), 
                Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
        LayoutInflater inflater = requireActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.dialog_city_search, null);

        EditText searchInput = view.findViewById(R.id.search_input);
        resultList = view.findViewById(R.id.result_list);
        View searchCityButton = view.findViewById(R.id.btn_search_city);

        adapter = new ArrayAdapter<>(requireContext(), 
            android.R.layout.simple_list_item_1, 
            new ArrayList<>());
        resultList.setAdapter(adapter);

        resultList.setOnItemClickListener((parent, v, position, id) -> {
            if (currentSearchType == SEARCH_TYPE_CITY) {
                if (position < addressResults.size()) {
                    Location location = addressResults.get(position);
                    if (listener != null) {
                        listener.onCitySelected(location);
                        dismiss();
                    }
                }
            } else {
                if (position < poiResults.size()) {
                    PoiItem poi = poiResults.get(position);
                    if (listener != null) {
                        Location location = new Location(
                            poi.getCityName(),
                            poi.getLatLonPoint().getLatitude(),
                            poi.getLatLonPoint().getLongitude()
                        );
                        location.setAddress(poi.getSnippet());
                        listener.onCitySelected(location);
                        dismiss();
                    }
                }
            }
        });

        // 城市搜索按钮
        searchCityButton.setOnClickListener(v -> {
            String query = searchInput.getText().toString().trim();
            if (!query.isEmpty()) {
                currentSearchType = SEARCH_TYPE_CITY;
                searchCity(query);
            }
        });

        return builder.setView(view)
                .setTitle("搜索城市")
                .setNegativeButton("取消", null)
                .create();
    }

    private void getCurrentCity() {
        LocationUtils.getCurrentLocation(requireContext(), new LocationUtils.LocationCallback() {
            @Override
            public void onLocationReceived(Location location) {
                Geocoder geocoder = new Geocoder(requireContext(), Locale.getDefault());
                try {
                    List<Address> addresses = geocoder.getFromLocation(
                        location.getLatitude(),
                        location.getLongitude(),
                        1
                    );
                    
                    if (addresses != null && !addresses.isEmpty()) {
                        Address address = addresses.get(0);
                        Location cityLocation = new Location(
                            address.getLocality(),  // 城市名
                            location.getLatitude(),
                            location.getLongitude()
                        );
                        
                        // 构建显示名称
                        StringBuilder displayName = new StringBuilder();
                        if (address.getAdminArea() != null) {  // 省份
                            displayName.append(address.getAdminArea()).append(", ");
                        }
                        displayName.append(address.getLocality());  // 城市
                        
                        // 清除之前的结果
                        addressResults.clear();
                        poiResults.clear();
                        adapter.clear();
                        
                        // 添加当前城市
                        adapter.add(displayName.toString());
                        addressResults.add(cityLocation);
                        adapter.notifyDataSetChanged();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(requireContext(), 
                        "获取城市信息失败: " + e.getMessage(), 
                        Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onLocationFailed(String error) {
                Toast.makeText(requireContext(), error, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private boolean checkNetworkAvailable() {
        ConnectivityManager cm = (ConnectivityManager) requireContext()
            .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) return false;
        
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        
        if (!isConnected) {
            Toast.makeText(requireContext(), "请检查网络连接", Toast.LENGTH_SHORT).show();
        }
        return isConnected;
    }

    private void showLoading(String message) {
        if (progressDialog == null) {
            progressDialog = new ProgressDialog(requireContext());
            progressDialog.setCancelable(false);
        }
        progressDialog.setMessage(message);
        progressDialog.show();
    }

    private void hideLoading() {
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        timeoutHandler.removeCallbacksAndMessages(null);
        if (locationClient != null) {
            locationClient.onDestroy();
        }
    }

    public interface OnCitySelectedListener {
        void onCitySelected(Location city);
    }

    public void setOnCitySelectedListener(OnCitySelectedListener listener) {
        this.listener = listener;
    }

    private void searchCity(String query) {
        if (!checkNetworkAvailable()) return;
        
        showLoading("正在搜索...");
        try {
            GeocodeSearch geocodeSearch = new GeocodeSearch(requireContext());
            geocodeSearch.setOnGeocodeSearchListener(this);
            
            GeocodeQuery geocodeQuery = new GeocodeQuery(query, "");
            geocodeSearch.getFromLocationNameAsyn(geocodeQuery);
        } catch (AMapException e) {
            hideLoading();
            Toast.makeText(requireContext(), "搜索失败: " + e.getErrorMessage(), 
                Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onGeocodeSearched(GeocodeResult result, int rCode) {
        hideLoading();
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getGeocodeAddressList() != null) {
                addressResults.clear();
                poiResults.clear();
                adapter.clear();
                
                for (GeocodeAddress address : result.getGeocodeAddressList()) {
                    String city = address.getCity();
                    if (city != null && !city.isEmpty()) {
                        Location location = new Location(
                            city,
                            address.getLatLonPoint().getLatitude(),
                            address.getLatLonPoint().getLongitude()
                        );
                        
                        // 构建显示名称
                        StringBuilder displayName = new StringBuilder();
                        if (address.getProvince() != null) {
                            displayName.append(address.getProvince()).append(", ");
                        }
                        displayName.append(city);
                        
                        adapter.add(displayName.toString());
                        addressResults.add(location);
                    }
                }

                if (addressResults.isEmpty()) {
                    Toast.makeText(requireContext(), "未找到相关城市", Toast.LENGTH_SHORT).show();
                }

                adapter.notifyDataSetChanged();
            }
        } else {
            Toast.makeText(requireContext(), "搜索失败，错误码: " + rCode, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
        // 反地理编码搜索回调，这里不需要实现
    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {
        // 这个方法可以留空，因为我们不需要单个 POI 的搜索结果
    }

    @Override
    public void onPoiSearched(PoiResult result, int rCode) {
        // 实现这个必需的方法
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getPois() != null) {
                poiResults.clear();
                adapter.clear();
                
                for (PoiItem poi : result.getPois()) {
                    poiResults.add(poi);
                    String displayName = poi.getTitle();
                    if (poi.getSnippet() != null && !poi.getSnippet().isEmpty()) {
                        displayName += "\n" + poi.getSnippet();
                    }
                    adapter.add(displayName);
                }

                if (poiResults.isEmpty()) {
                    Toast.makeText(requireContext(), "未找到相关位置", Toast.LENGTH_SHORT).show();
                }
            }
        } else {
            Toast.makeText(requireContext(), "搜索失败，错误码: " + rCode, Toast.LENGTH_SHORT).show();
        }
    }
} 